﻿namespace YidanSoft.Library.EditorUtility.Menus
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Text;
    using System.Runtime.CompilerServices;
    using System.Threading;
    using System.Windows.Forms;
    using YidanSoft.Library.EditorUtility.Collections;
    using YidanSoft.Library.EditorUtility.General;
    using YidanSoft.Library.EditorUtility.Win32;

    [Designer(typeof(MenuControlDesigner)), DefaultEvent("PopupStart"), DefaultProperty("MenuCommands"), ToolboxBitmap(typeof(MenuControl))]
    public class MenuControl : ContainerControl, IMessageFilter
    {
        protected const int _boxExpandSides = 2;
        protected const int _boxExpandUpper = 1;
        protected const int _breadthGap = 5;
        protected const int _chevronBreadth = 10;
        protected const int _chevronIndex = 0;
        protected const int _chevronLength = 10;
        protected MenuCommand _chevronStartCommand;
        protected YidanSoft.Library.EditorUtility.General.Direction _direction;
        protected bool _dismissTransfer;
        protected ArrayList _drawCommands;
        protected bool _drawUpwards;
        protected bool _ignoreEscapeUp;
        protected bool _ignoreMouseMove;
        protected const int _lengthGap = 3;
        protected bool _manualFocus;
        protected MenuCommandCollection _menuCommands;
        protected static ImageList _menuImages = null;
        protected bool _mouseOver;
        protected bool _multiLine;
        protected IntPtr _oldFocus;
        protected bool _plainAsBlock;
        protected PopupMenu _popupMenu;
        protected int _rowHeight;
        protected int _rowWidth;
        protected bool _selected;
        protected const int _separatorWidth = 15;
        protected const int _shadowGap = 3;
        protected const int _shadowYOffset = 3;
        protected VisualStyle _style;
        protected const int _subMenuBorderAdjust = 2;
        protected static bool _supportsLayered = false;
        protected int _trackItem;
        private PopupHandler PopupEnd;
        private PopupHandler PopupStart;
        protected readonly int WM_OPERATEMENU = 0x401;

        public event PopupHandler PopupEnd
        {
            add
            {
                PopupHandler handler2;
                PopupHandler popupEnd = this.PopupEnd;
                do
                {
                    handler2 = popupEnd;
                    PopupHandler handler3 = (PopupHandler) Delegate.Combine(handler2, value);
                    popupEnd = Interlocked.CompareExchange<PopupHandler>(ref this.PopupEnd, handler3, handler2);
                }
                while (popupEnd != handler2);
            }
            remove
            {
                PopupHandler handler2;
                PopupHandler popupEnd = this.PopupEnd;
                do
                {
                    handler2 = popupEnd;
                    PopupHandler handler3 = (PopupHandler) Delegate.Remove(handler2, value);
                    popupEnd = Interlocked.CompareExchange<PopupHandler>(ref this.PopupEnd, handler3, handler2);
                }
                while (popupEnd != handler2);
            }
        }

        public event PopupHandler PopupStart
        {
            add
            {
                PopupHandler handler2;
                PopupHandler popupStart = this.PopupStart;
                do
                {
                    handler2 = popupStart;
                    PopupHandler handler3 = (PopupHandler) Delegate.Combine(handler2, value);
                    popupStart = Interlocked.CompareExchange<PopupHandler>(ref this.PopupStart, handler3, handler2);
                }
                while (popupStart != handler2);
            }
            remove
            {
                PopupHandler handler2;
                PopupHandler popupStart = this.PopupStart;
                do
                {
                    handler2 = popupStart;
                    PopupHandler handler3 = (PopupHandler) Delegate.Remove(handler2, value);
                    popupStart = Interlocked.CompareExchange<PopupHandler>(ref this.PopupStart, handler3, handler2);
                }
                while (popupStart != handler2);
            }
        }

        static MenuControl()
        {
            _menuImages = ResourceUtil.LoadImageListResource(System.Type.GetType("YidanSoft.Library.EditorUtility.Menus.MenuControl"), "Resources.ImagesMenu", "MenuControlImages", new Size(10, 10), true, new Point(0, 0));
            _supportsLayered = OSFeature.Feature.GetVersionPresent(OSFeature.LayeredWindows) != null;
        }

        public MenuControl()
        {
            this.Dock = DockStyle.Top;
            this._trackItem = -1;
            this._selected = false;
            this._multiLine = false;
            this._popupMenu = null;
            this._mouseOver = false;
            this._manualFocus = false;
            this._drawUpwards = false;
            this._plainAsBlock = false;
            this._oldFocus = IntPtr.Zero;
            this._ignoreEscapeUp = false;
            this._ignoreMouseMove = false;
            this._dismissTransfer = false;
            this._style = VisualStyle.IDE;
            this._chevronStartCommand = null;
            this._direction = YidanSoft.Library.EditorUtility.General.Direction.Horizontal;
            this._menuCommands = new MenuCommandCollection();
            base.SetStyle(ControlStyles.DoubleBuffer, true);
            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.Selectable, false);
            this._menuCommands.Cleared += new CollectionWithEvents.CollectionClear(this.OnCollectionCleared);
            this._menuCommands.Inserted += new CollectionWithEvents.CollectionChange(this.OnCollectionInserted);
            this._menuCommands.Removed += new CollectionWithEvents.CollectionChange(this.OnCollectionRemoved);
            this.BackColor = SystemColors.Control;
            base.TabStop = false;
            this.Font = SystemInformation.MenuFont;
            this._rowWidth = this._rowHeight = (this.Font.Height + 10) + 1;
            base.Height = this._rowHeight;
            Application.AddMessageFilter(this);
        }

        protected void DrawAllCommands(Graphics g)
        {
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                YidanSoft.Library.EditorUtility.Menus.DrawCommand dc = this._drawCommands[i] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                this.DrawSingleCommand(g, dc, i == this._trackItem);
            }
        }

        protected void DrawCommand(int drawItem, bool tracked)
        {
            using (Graphics graphics = base.CreateGraphics())
            {
                this.DrawSingleCommand(graphics, this._drawCommands[drawItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand, tracked);
            }
        }

        internal void DrawSelectionUpwards()
        {
            if ((this._trackItem != -1) && this._selected)
            {
                this._drawUpwards = true;
                this.DrawCommand(this._trackItem, true);
            }
        }

        internal void DrawSingleCommand(Graphics g, YidanSoft.Library.EditorUtility.Menus.DrawCommand dc, bool tracked)
        {
            Rectangle drawRect = dc.DrawRect;
            MenuCommand menuCommand = dc.MenuCommand;
            Rectangle rect = drawRect;
            rect.Width += 3;
            rect.Height += 3;
            using (SolidBrush brush = new SolidBrush(SystemColors.Control))
            {
                g.FillRectangle(brush, rect);
            }
            if (!dc.Separator)
            {
                Rectangle rectangle3;
                SolidBrush brush3;
                if (dc.Chevron)
                {
                    rectangle3 = new Rectangle(drawRect.Left + 3, drawRect.Top + 1, drawRect.Width - 6, drawRect.Height - 2);
                }
                else
                {
                    rectangle3 = new Rectangle(drawRect.Left + 3, drawRect.Top + 3, drawRect.Width - 6, drawRect.Height - 6);
                }
                if (dc.Enabled && tracked)
                {
                    Rectangle rectangle4;
                    Pen pen;
                    SolidBrush brush4;
                    if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                    {
                        rectangle4 = new Rectangle(rectangle3.Left - 2, rectangle3.Top - 1, rectangle3.Width + 4, rectangle3.Height + 1);
                    }
                    else if (!dc.Chevron)
                    {
                        rectangle4 = new Rectangle(rectangle3.Left, rectangle3.Top - 2, rectangle3.Width - 2, rectangle3.Height + 4);
                    }
                    else
                    {
                        rectangle4 = rectangle3;
                    }
                    switch (this._style)
                    {
                        case VisualStyle.IDE:
                        {
                            int top;
                            int num4;
                            SolidBrush brush2;
                            if (!this._selected)
                            {
                                using (Pen pen2 = new Pen(ColorUtil.VSNetBorderColor))
                                {
                                    using (brush3 = new SolidBrush(Color.White))
                                    {
                                        g.FillRectangle(brush3, rectangle4);
                                    }
                                    using (brush4 = new SolidBrush(Color.FromArgb(70, ColorUtil.VSNetBorderColor)))
                                    {
                                        g.FillRectangle(brush4, rectangle4);
                                        g.DrawRectangle(pen2, rectangle4);
                                    }
                                }
                                break;
                            }
                            g.FillRectangle(SystemBrushes.ControlLight, rectangle4);
                            int x = rectangle4.Right + 1;
                            int bottom = rectangle4.Bottom;
                            if (!this._drawUpwards || (this._direction != YidanSoft.Library.EditorUtility.General.Direction.Horizontal))
                            {
                                using (pen = new Pen(SystemColors.ControlDark))
                                {
                                    g.DrawRectangle(pen, rectangle4);
                                }
                                if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                                {
                                    using (pen = new Pen(SystemColors.ControlLight))
                                    {
                                        g.DrawLine(pen, rectangle4.Left, rectangle4.Bottom, rectangle4.Right, rectangle4.Bottom);
                                    }
                                    top = rectangle4.Top + 3;
                                    if (_supportsLayered && (this._style == VisualStyle.IDE))
                                    {
                                        brush2 = new SolidBrush(Color.FromArgb(0x40, 0, 0, 0));
                                    }
                                    else
                                    {
                                        brush2 = new SolidBrush(SystemColors.ControlDark);
                                    }
                                    g.FillRectangle(brush2, new Rectangle(x, top, 3, bottom - top));
                                    brush2.Dispose();
                                }
                                else
                                {
                                    using (pen = new Pen(SystemColors.ControlLight))
                                    {
                                        g.DrawLine(pen, rectangle4.Right, rectangle4.Top, rectangle4.Right, rectangle4.Bottom);
                                    }
                                    num4 = rectangle4.Left + 3;
                                    if (_supportsLayered && (this._style == VisualStyle.IDE))
                                    {
                                        brush2 = new SolidBrush(Color.FromArgb(0x40, 0, 0, 0));
                                    }
                                    else
                                    {
                                        brush2 = new SolidBrush(SystemColors.ControlDark);
                                    }
                                    g.FillRectangle(brush2, new Rectangle(num4, bottom + 1, (bottom - num4) - 3, 3));
                                    brush2.Dispose();
                                }
                                break;
                            }
                            using (pen = new Pen(SystemColors.ControlDark))
                            {
                                g.DrawRectangle(pen, rectangle4.Left, rectangle4.Top - 3, rectangle4.Width, rectangle4.Height + 3);
                            }
                            using (pen = new Pen(SystemColors.ControlLight))
                            {
                                g.DrawLine(pen, rectangle4.Left + 1, rectangle4.Top, rectangle4.Right - 2, rectangle4.Top);
                            }
                            top = rectangle4.Top;
                            num4 = rectangle4.Left + 3;
                            if (_supportsLayered && (this._style == VisualStyle.IDE))
                            {
                                brush2 = new SolidBrush(Color.FromArgb(0x40, 0, 0, 0));
                            }
                            else
                            {
                                brush2 = new SolidBrush(SystemColors.ControlDark);
                            }
                            g.FillRectangle(brush2, new Rectangle(x, (top + 3) - 1, 3, (bottom - top) - 6));
                            brush2.Dispose();
                            break;
                        }
                        case VisualStyle.Plain:
                            if (!this._plainAsBlock)
                            {
                                using (Pen pen3 = new Pen(SystemColors.ControlLightLight))
                                {
                                    using (pen = new Pen(SystemColors.ControlDark))
                                    {
                                        if (this._selected)
                                        {
                                            g.DrawLine(pen, rectangle4.Left, rectangle4.Bottom, rectangle4.Left, rectangle4.Top);
                                            g.DrawLine(pen, rectangle4.Left, rectangle4.Top, rectangle4.Right, rectangle4.Top);
                                            g.DrawLine(pen3, rectangle4.Right, rectangle4.Top, rectangle4.Right, rectangle4.Bottom);
                                            g.DrawLine(pen3, rectangle4.Right, rectangle4.Bottom, rectangle4.Left, rectangle4.Bottom);
                                        }
                                        else
                                        {
                                            g.DrawLine(pen3, rectangle4.Left, rectangle4.Bottom, rectangle4.Left, rectangle4.Top);
                                            g.DrawLine(pen3, rectangle4.Left, rectangle4.Top, rectangle4.Right, rectangle4.Top);
                                            g.DrawLine(pen, rectangle4.Right, rectangle4.Top, rectangle4.Right, rectangle4.Bottom);
                                            g.DrawLine(pen, rectangle4.Right, rectangle4.Bottom, rectangle4.Left, rectangle4.Bottom);
                                        }
                                    }
                                }
                                break;
                            }
                            using (brush4 = new SolidBrush(ColorUtil.VSNetBorderColor))
                            {
                                g.FillRectangle(brush4, drawRect);
                            }
                            break;
                    }
                }
                if (dc.Chevron)
                {
                    int y = drawRect.Top;
                    int num6 = drawRect.X + ((drawRect.Width - 10) / 2);
                    if (this._selected)
                    {
                        num6++;
                        y++;
                    }
                    g.DrawImage(_menuImages.Images[0], num6, y);
                }
                else
                {
                    StringFormat format = new StringFormat();
                    format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap;
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Center;
                    format.HotkeyPrefix = HotkeyPrefix.Show;
                    if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Vertical)
                    {
                        format.FormatFlags |= StringFormatFlags.DirectionVertical;
                    }
                    if (dc.Enabled)
                    {
                        SolidBrush brush5;
                        if ((tracked && (this._style == VisualStyle.Plain)) && this._plainAsBlock)
                        {
                            if (this._selected)
                            {
                                rectangle3.X += 2;
                                rectangle3.Y += 2;
                            }
                            using (brush5 = new SolidBrush(SystemColors.HighlightText))
                            {
                                g.DrawString(menuCommand.Text, this.Font, brush5, rectangle3, format);
                            }
                        }
                        else
                        {
                            using (brush5 = new SolidBrush(SystemColors.MenuText))
                            {
                                g.DrawString(menuCommand.Text, this.Font, brush5, rectangle3, format);
                            }
                        }
                    }
                    else
                    {
                        Rectangle layoutRectangle = rectangle3;
                        layoutRectangle.Offset(1, 1);
                        using (brush3 = new SolidBrush(SystemColors.HighlightText))
                        {
                            g.DrawString(menuCommand.Text, this.Font, brush3, layoutRectangle, format);
                        }
                        using (SolidBrush brush6 = new SolidBrush(SystemColors.GrayText))
                        {
                            g.DrawString(menuCommand.Text, this.Font, brush6, rectangle3, format);
                        }
                    }
                }
            }
        }

        protected bool GenerateShortcut(Shortcut sc, MenuCommandCollection mcc)
        {
            foreach (MenuCommand command in mcc)
            {
                if (command.Enabled && (command.Shortcut == sc))
                {
                    command.OnClick(EventArgs.Empty);
                    return true;
                }
                if ((command.MenuCommands.Count > 0) && this.GenerateShortcut(sc, command.MenuCommands))
                {
                    return true;
                }
            }
            return false;
        }

        protected void GrabTheFocus()
        {
            this._oldFocus = WindowsAPI.GetFocus();
            base.Focus();
        }

        protected void OnCollectionCleared()
        {
            this._selected = false;
            this._trackItem = -1;
            this.Recalculate();
            base.Invalidate();
        }

        protected void OnCollectionInserted(int index, object value)
        {
            MenuCommand command = value as MenuCommand;
            command.PropertyChanged += new MenuCommand.PropChangeHandler(this.OnCommandChanged);
            this._selected = false;
            this._trackItem = -1;
            this.Recalculate();
            base.Invalidate();
        }

        protected void OnCollectionRemoved(int index, object value)
        {
            this._selected = false;
            this._trackItem = -1;
            this.Recalculate();
            base.Invalidate();
        }

        protected void OnCommandChanged(MenuCommand item, MenuCommand.Property prop)
        {
            this.Recalculate();
            base.Invalidate();
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left:
                    if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                    {
                        this.ProcessMoveLeft(false);
                    }
                    if (this._selected)
                    {
                        this._ignoreMouseMove = true;
                    }
                    goto Label_0138;

                case Keys.Up:
                    if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Vertical)
                    {
                        this.ProcessMoveLeft(false);
                    }
                    goto Label_0138;

                case Keys.Right:
                    if (this._direction != YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                    {
                        this.ProcessMoveDown();
                        break;
                    }
                    this.ProcessMoveRight(false);
                    break;

                case Keys.Down:
                    if (this._direction != YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                    {
                        this.ProcessMoveRight(false);
                    }
                    else
                    {
                        this.ProcessMoveDown();
                    }
                    goto Label_0138;

                case Keys.Escape:
                    if ((this._trackItem != -1) && this._selected)
                    {
                        if (this._popupMenu == null)
                        {
                            this._selected = false;
                            this._drawUpwards = false;
                            this.DrawCommand(this._trackItem, true);
                            this.ReturnTheFocus();
                            e.Handled = true;
                        }
                        else
                        {
                            this._ignoreEscapeUp = true;
                        }
                    }
                    goto Label_0138;

                default:
                    goto Label_0138;
            }
            if (this._selected)
            {
                this._ignoreMouseMove = true;
            }
        Label_0138:
            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                if ((this._manualFocus && !this._selected) && !this._ignoreEscapeUp)
                {
                    this._manualFocus = false;
                    this._trackItem = this.SwitchTrackingItem(this._trackItem, -1);
                    this.ReturnTheFocus();
                }
                this._ignoreEscapeUp = false;
            }
            else
            {
                this.ProcessMnemonicKey((char) e.KeyValue);
                if (this._selected)
                {
                    this._ignoreMouseMove = true;
                }
            }
            base.OnKeyUp(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            this._manualFocus = false;
            this._trackItem = this.SwitchTrackingItem(this._trackItem, -1);
            this._oldFocus = IntPtr.Zero;
            this._mouseOver = false;
            base.OnLostFocus(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            Point pt = new Point(e.X, e.Y);
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[i] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                if (command.DrawRect.Contains(pt))
                {
                    if (this._selected)
                    {
                        if ((this._trackItem == i) && (this._popupMenu != null))
                        {
                            this._popupMenu.Dismiss();
                            this._popupMenu = null;
                        }
                    }
                    else
                    {
                        this._selected = true;
                        this._drawUpwards = false;
                        this.GrabTheFocus();
                        if (this._trackItem != i)
                        {
                            this._trackItem = this.SwitchTrackingItem(this._trackItem, i);
                        }
                        else
                        {
                            this.DrawCommand(this._trackItem, true);
                        }
                        if (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0))
                        {
                            WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 1, 0);
                        }
                    }
                    break;
                }
            }
            base.OnMouseDown(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            this._mouseOver = false;
            if ((!this._manualFocus && (this._trackItem != -1)) && !this._selected)
            {
                this._trackItem = this.SwitchTrackingItem(this._trackItem, -1);
            }
            base.OnMouseLeave(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (this._ignoreMouseMove)
            {
                this._ignoreMouseMove = false;
            }
            else
            {
                if (!this._mouseOver)
                {
                    TRACKMOUSEEVENTS tme = new TRACKMOUSEEVENTS();
                    tme.cbSize = 0x10;
                    tme.dwFlags = 2;
                    tme.hWnd = base.Handle;
                    tme.dwHoverTime = 0;
                    WindowsAPI.TrackMouseEvent(ref tme);
                    this._mouseOver = true;
                }
                Form form = base.FindForm();
                if ((form != null) && form.ContainsFocus)
                {
                    Point pt = new Point(e.X, e.Y);
                    int newItem = 0;
                    newItem = 0;
                    while (newItem < this._drawCommands.Count)
                    {
                        YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[newItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                        if (command.DrawRect.Contains(pt))
                        {
                            if (this._trackItem != newItem)
                            {
                                if (this._selected)
                                {
                                    if (this._popupMenu != null)
                                    {
                                        this._dismissTransfer = true;
                                        this._popupMenu.Dismiss();
                                        this._drawUpwards = false;
                                    }
                                    this._trackItem = this.SwitchTrackingItem(this._trackItem, newItem);
                                    if (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0))
                                    {
                                        WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 1, 0);
                                    }
                                }
                                else
                                {
                                    this._trackItem = this.SwitchTrackingItem(this._trackItem, newItem);
                                }
                            }
                            break;
                        }
                        newItem++;
                    }
                    if (!this._selected && (newItem == this._drawCommands.Count))
                    {
                        this._trackItem = this.SwitchTrackingItem(this._trackItem, -1);
                    }
                }
            }
            base.OnMouseMove(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (((this._trackItem != -1) && this._selected) && (this._popupMenu == null))
            {
                this._selected = false;
                this._drawUpwards = false;
                this.DrawCommand(this._trackItem, true);
                this.ReturnTheFocus();
            }
            base.OnMouseUp(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            this.DrawAllCommands(e.Graphics);
            base.OnPaint(e);
        }

        protected void OnPopupEnd(MenuCommand mc)
        {
            if (this.PopupEnd != null)
            {
                this.PopupEnd(mc);
            }
        }

        protected void OnPopupStart(MenuCommand mc)
        {
            if (this.PopupStart != null)
            {
                this.PopupStart(mc);
            }
        }

        protected override void OnResize(EventArgs e)
        {
            this.Recalculate();
            base.Invalidate();
            base.OnResize(e);
        }

        protected void OnWM_GETDLGCODE(ref Message m)
        {
            m.Result = (IntPtr) 4L;
        }

        protected void OnWM_OPERATEMENU(ref Message m)
        {
            if (this._trackItem != -1)
            {
                YidanSoft.Library.EditorUtility.Menus.DrawCommand dc = this._drawCommands[this._trackItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                this.OperateSubMenu(dc, m.LParam != IntPtr.Zero, m.WParam != IntPtr.Zero);
            }
        }

        internal void OperateSubMenu(YidanSoft.Library.EditorUtility.Menus.DrawCommand dc, bool selectFirst, bool trackRemove)
        {
            Point point;
            Point point2;
            int num;
            Rectangle drawRect = dc.DrawRect;
            if (this._style == VisualStyle.IDE)
            {
                if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                {
                    point = base.PointToScreen(new Point(dc.DrawRect.Left + 1, (drawRect.Bottom - 3) - 1));
                }
                else
                {
                    point = base.PointToScreen(new Point(dc.DrawRect.Right - 5, (drawRect.Top + 2) - 1));
                }
            }
            else if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
            {
                point = base.PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom));
            }
            else
            {
                point = base.PointToScreen(new Point(dc.DrawRect.Right, drawRect.Top));
            }
            if (this._style == VisualStyle.IDE)
            {
                if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                {
                    point2 = base.PointToScreen(new Point(dc.DrawRect.Left + 1, (drawRect.Top + 3) + 1));
                }
                else
                {
                    point2 = base.PointToScreen(new Point(dc.DrawRect.Right - 5, drawRect.Bottom + 3));
                }
            }
            else if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
            {
                point2 = base.PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top));
            }
            else
            {
                point2 = base.PointToScreen(new Point(dc.DrawRect.Right, drawRect.Bottom));
            }
            if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
            {
                num = dc.DrawRect.Width - 2;
            }
            else
            {
                num = dc.DrawRect.Height - 2;
            }
            this._popupMenu = new PopupMenu();
            this._popupMenu.Style = this.Style;
            int returnDir = 0;
            if (dc.Chevron)
            {
                MenuCommandCollection menuCollection = new MenuCommandCollection();
                bool flag = false;
                foreach (MenuCommand command in this._menuCommands)
                {
                    if (!(flag || (command != this._chevronStartCommand)))
                    {
                        flag = true;
                    }
                    if (flag)
                    {
                        menuCollection.Add(command);
                    }
                }
                this._popupMenu.TrackPopup(point, point2, this._direction, menuCollection, num, selectFirst, this, ref returnDir);
            }
            else
            {
                this.OnPopupStart(dc.MenuCommand);
                this._popupMenu.TrackPopup(point, point2, this._direction, dc.MenuCommand.MenuCommands, num, selectFirst, this, ref returnDir);
                this.OnPopupEnd(dc.MenuCommand);
            }
            this._popupMenu = null;
            if (returnDir != 0)
            {
                if (!this._manualFocus)
                {
                    this._manualFocus = true;
                    this.GrabTheFocus();
                }
                if (returnDir < 0)
                {
                    this.ProcessMoveLeft(true);
                }
                else
                {
                    this.ProcessMoveRight(true);
                }
                this._ignoreMouseMove = true;
            }
            else if (!this._dismissTransfer)
            {
                this._selected = false;
                this._drawUpwards = false;
                if (trackRemove)
                {
                    this.ReturnTheFocus();
                    this._trackItem = this.SwitchTrackingItem(this._trackItem, -1);
                }
                else
                {
                    this.DrawCommand(this._trackItem, true);
                }
            }
            else
            {
                this._dismissTransfer = false;
            }
        }

        public bool PreFilterMessage(ref Message msg)
        {
            Form form = base.FindForm();
            if ((form != null) && form.ContainsFocus)
            {
                Shortcut shortcut;
                switch (msg.Msg)
                {
                    case 0x101:
                    {
                        ushort keyState = WindowsAPI.GetKeyState(0x10);
                        ushort num2 = WindowsAPI.GetKeyState(0x11);
                        int wParam = (int) msg.WParam;
                        if ((keyState & 0x8000) != 0)
                        {
                            wParam += 0x10000;
                        }
                        if ((num2 & 0x8000) != 0)
                        {
                            wParam += 0x20000;
                        }
                        shortcut = (Shortcut) wParam;
                        return this.GenerateShortcut(shortcut, this._menuCommands);
                    }
                    case 0x105:
                        if (((int) msg.WParam) != 0x12)
                        {
                            shortcut = (Shortcut) (0x40000 + ((int) msg.WParam));
                            return (this.GenerateShortcut(shortcut, this._menuCommands) || this.ProcessMnemonicKey((char) ((int) msg.WParam)));
                        }
                        if (this._manualFocus)
                        {
                            break;
                        }
                        if (this._drawCommands.Count > 0)
                        {
                            if (this._trackItem == -1)
                            {
                                for (int i = 0; i < this._drawCommands.Count; i++)
                                {
                                    YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[i] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                                    if (!(command.Separator || (!command.Chevron && !command.MenuCommand.Enabled)))
                                    {
                                        this._trackItem = this.SwitchTrackingItem(-1, i);
                                        break;
                                    }
                                }
                            }
                            this._manualFocus = true;
                            this.GrabTheFocus();
                        }
                        return true;

                    case 560:
                    case 0x234:
                        return true;
                }
            }
            return false;
        }

        protected bool ProcessMnemonicKey(char key)
        {
            if (!this._manualFocus)
            {
                this._manualFocus = true;
                this.GrabTheFocus();
            }
            if (!this._selected)
            {
                for (int i = 0; i < this._drawCommands.Count; i++)
                {
                    YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[i] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                    if (((command.MenuCommand != null) && command.MenuCommand.Enabled) && (key == command.Mnemonic))
                    {
                        this._selected = true;
                        this._drawUpwards = false;
                        if (this._trackItem != i)
                        {
                            this._trackItem = this.SwitchTrackingItem(this._trackItem, i);
                        }
                        else
                        {
                            this.DrawCommand(this._trackItem, true);
                        }
                        if (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0))
                        {
                            WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 0, 1);
                        }
                        else
                        {
                            command.MenuCommand.OnClick(EventArgs.Empty);
                        }
                        return true;
                    }
                }
            }
            return false;
        }

        protected void ProcessMoveDown()
        {
            if (((this._popupMenu == null) && (this._trackItem != -1)) && !this._selected)
            {
                YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[this._trackItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                if (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0))
                {
                    this._selected = true;
                    this._drawUpwards = false;
                    this.DrawCommand(this._trackItem, true);
                    WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 0, 1);
                }
            }
        }

        protected void ProcessMoveLeft(bool select)
        {
            if (this._popupMenu == null)
            {
                int newItem = this._trackItem;
                int num2 = newItem;
                for (int i = 0; i < this._drawCommands.Count; i++)
                {
                    newItem--;
                    if (newItem == num2)
                    {
                        break;
                    }
                    if (newItem < 0)
                    {
                        newItem = this._drawCommands.Count - 1;
                    }
                    YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[newItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                    if (!(command.Separator || (!command.Chevron && !command.MenuCommand.Enabled)) && (newItem != this._trackItem))
                    {
                        this._trackItem = this.SwitchTrackingItem(this._trackItem, newItem);
                        if (this._selected && (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0)))
                        {
                            WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 0, 1);
                        }
                        break;
                    }
                }
            }
        }

        protected void ProcessMoveRight(bool select)
        {
            if (this._popupMenu == null)
            {
                int newItem = this._trackItem;
                int num2 = newItem;
                for (int i = 0; i < this._drawCommands.Count; i++)
                {
                    newItem++;
                    if (newItem >= this._drawCommands.Count)
                    {
                        newItem = 0;
                    }
                    YidanSoft.Library.EditorUtility.Menus.DrawCommand command = this._drawCommands[newItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                    if (!(command.Separator || (!command.Chevron && !command.MenuCommand.Enabled)) && (newItem != this._trackItem))
                    {
                        this._trackItem = this.SwitchTrackingItem(this._trackItem, newItem);
                        if (this._selected && (command.Chevron || (command.MenuCommand.MenuCommands.Count > 0)))
                        {
                            WindowsAPI.PostMessage(base.Handle, this.WM_OPERATEMENU, 0, 1);
                        }
                        break;
                    }
                }
            }
        }

        protected void Recalculate()
        {
            int width;
            if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
            {
                width = base.Width;
            }
            else
            {
                width = base.Height;
            }
            if (width <= 0)
            {
                return;
            }
            int num2 = 0;
            int num3 = 0;
            this._drawCommands = new ArrayList();
            int num4 = 6;
            int height = base.Height;
            int x = 0;
            if (this._chevronStartCommand != null)
            {
                width -= num4 + 10;
            }
            this._chevronStartCommand = null;
            using (Graphics graphics = base.CreateGraphics())
            {
                int num7 = 0;
                foreach (MenuCommand command in this._menuCommands)
                {
                    command.OnUpdate(EventArgs.Empty);
                    if (command.Visible)
                    {
                        Rectangle rectangle;
                        int num8 = 0;
                        if (command.Text == "-")
                        {
                            num8 = 15;
                        }
                        else
                        {
                            SizeF ef = graphics.MeasureString(command.Text, this.Font);
                            num8 = (num4 + ((int) ef.Width)) + 1;
                        }
                        if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                        {
                            rectangle = new Rectangle(x, this._rowHeight * num2, num8, this._rowHeight);
                        }
                        else
                        {
                            rectangle = new Rectangle(this._rowWidth * num2, x, this._rowWidth, num8);
                        }
                        x += num8;
                        num3++;
                        if ((x > width) && (num3 > 1))
                        {
                            if (this._multiLine)
                            {
                                num2++;
                                num3 = 1;
                                x = num8;
                                if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                                {
                                    rectangle.X = 0;
                                    rectangle.Y += this._rowHeight;
                                }
                                else
                                {
                                    rectangle.X += this._rowWidth;
                                    rectangle.Y = 0;
                                }
                            }
                            else
                            {
                                if (num7 <= this._trackItem)
                                {
                                    this._trackItem = -1;
                                }
                                this._chevronStartCommand = command;
                                if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
                                {
                                    rectangle.Y = 0;
                                    rectangle.Width = num4 + 10;
                                    rectangle.X = base.Width - rectangle.Width;
                                    rectangle.Height = this._rowHeight;
                                }
                                else
                                {
                                    rectangle.X = 0;
                                    rectangle.Height = num4 + 10;
                                    rectangle.Y = base.Height - (num4 + 10);
                                    rectangle.Width = this._rowWidth;
                                }
                                this._drawCommands.Add(new YidanSoft.Library.EditorUtility.Menus.DrawCommand(rectangle));
                                goto Label_0305;
                            }
                        }
                        this._drawCommands.Add(new YidanSoft.Library.EditorUtility.Menus.DrawCommand(command, rectangle));
                        num7++;
                    }
                }
            }
        Label_0305:
            if (this._direction == YidanSoft.Library.EditorUtility.General.Direction.Horizontal)
            {
                int num9 = (num2 + 1) * this._rowHeight;
                if (base.Height != num9)
                {
                    base.Height = num9;
                }
            }
            else
            {
                int num10 = (num2 + 1) * this._rowWidth;
                if (base.Width != num10)
                {
                    base.Width = num10;
                }
            }
        }

        protected void ReturnTheFocus()
        {
            if (this._oldFocus != IntPtr.Zero)
            {
                WindowsAPI.SetFocus(this._oldFocus);
                this._oldFocus = IntPtr.Zero;
            }
            this._manualFocus = false;
        }

        protected int SwitchTrackingItem(int oldItem, int newItem)
        {
            using (Graphics graphics = base.CreateGraphics())
            {
                YidanSoft.Library.EditorUtility.Menus.DrawCommand command;
                if (oldItem != -1)
                {
                    command = this._drawCommands[oldItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                    this.DrawSingleCommand(graphics, this._drawCommands[oldItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand, false);
                }
                this._trackItem = newItem;
                if (this._trackItem != -1)
                {
                    command = this._drawCommands[this._trackItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand;
                    this.DrawSingleCommand(graphics, this._drawCommands[this._trackItem] as YidanSoft.Library.EditorUtility.Menus.DrawCommand, true);
                }
            }
            return this._trackItem;
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == this.WM_OPERATEMENU)
            {
                this.OnWM_OPERATEMENU(ref m);
            }
            else if (m.Msg == 0x87)
            {
                this.OnWM_GETDLGCODE(ref m);
                return;
            }
            base.WndProc(ref m);
        }

        [Category("Appearance")]
        public YidanSoft.Library.EditorUtility.General.Direction Direction
        {
            get
            {
                return this._direction;
            }
            set
            {
                if (this._direction != value)
                {
                    this._direction = value;
                    this.Recalculate();
                    base.Invalidate();
                }
            }
        }

        public override DockStyle Dock
        {
            get
            {
                return base.Dock;
            }
            set
            {
                base.Dock = value;
                switch (value)
                {
                    case DockStyle.None:
                        this._direction = YidanSoft.Library.EditorUtility.General.Direction.Horizontal;
                        break;

                    case DockStyle.Top:
                    case DockStyle.Bottom:
                        base.Height = 0;
                        this._direction = YidanSoft.Library.EditorUtility.General.Direction.Horizontal;
                        break;

                    case DockStyle.Left:
                    case DockStyle.Right:
                        base.Width = 0;
                        this._direction = YidanSoft.Library.EditorUtility.General.Direction.Vertical;
                        break;
                }
                this.Recalculate();
                base.Invalidate();
            }
        }

        [Category("Appearance")]
        public override System.Drawing.Font Font
        {
            get
            {
                return base.Font;
            }
            set
            {
                base.Font = value;
                this._rowHeight = this.Font.Height + 6;
                this.Recalculate();
                base.Invalidate();
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behaviour")]
        public MenuCommandCollection MenuCommands
        {
            get
            {
                return this._menuCommands;
            }
            set
            {
                this._menuCommands.Clear();
                this._menuCommands = value;
                this.Recalculate();
                base.Invalidate();
            }
        }

        [DefaultValue(false), Category("Appearance")]
        public bool MultiLine
        {
            get
            {
                return this._multiLine;
            }
            set
            {
                if (this._multiLine != value)
                {
                    this._multiLine = value;
                    this.Recalculate();
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(false), Category("Appearance")]
        public bool PlainAsBlock
        {
            get
            {
                return this._plainAsBlock;
            }
            set
            {
                if (this._plainAsBlock != value)
                {
                    this._plainAsBlock = value;
                    this.Recalculate();
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance")]
        public VisualStyle Style
        {
            get
            {
                return this._style;
            }
            set
            {
                if (this._style != value)
                {
                    this._style = value;
                    this.Recalculate();
                    base.Invalidate();
                }
            }
        }

        public delegate void PopupHandler(MenuCommand item);
    }
}

